package com.exchange.controller;

import com.exchange.dto.MerchantDto;
import com.exchange.dto.UserDto;
import com.exchange.entity.Merchant;
import com.exchange.entity.User;
import com.exchange.service.MerchantService;
import com.exchange.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;

@RestController
@RequestMapping("/api/registration")
@CrossOrigin(origins = "*")
public class RegistrationController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private MerchantService merchantService;
    
    // Endpoint for merchant registration
    @PostMapping("/merchant")
    public ResponseEntity<?> registerMerchant(@RequestBody MerchantRegistrationRequest request) {
        // Check if username or email already exists
        if (userService.existsByUsername(request.getUsername())) {
            return ResponseEntity.badRequest().body(new ErrorResponse("Username is already taken"));
        }
        
        if (userService.existsByEmail(request.getEmail())) {
            return ResponseEntity.badRequest().body(new ErrorResponse("Email is already in use"));
        }
        
        // Create user account
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setPassword(request.getPassword());
        user.setPhone(request.getPhone());
        user.setUserType(User.UserType.MERCHANT);
        
        UserDto userDto = userService.createUser(user);
        
        // Create merchant profile
        Merchant merchant = new Merchant();
        merchant.setUserId(userDto.getId());
        merchant.setBusinessName(request.getBusinessName());
        merchant.setBusinessLicense(request.getBusinessLicense());
        merchant.setContactPerson(request.getContactPerson());
        merchant.setAddress(request.getAddress());
        merchant.setSubscriptionType(Merchant.SubscriptionType.FREE);
        merchant.setSubscriptionStartDate(LocalDate.now());
        merchant.setSubscriptionEndDate(LocalDate.now().plusDays(30)); // Default 30-day free trial
        merchant.setMaxProducts(request.getMaxProducts() != null ? request.getMaxProducts() : 10);
        merchant.setMaxExchangeCodes(request.getMaxExchangeCodes() != null ? request.getMaxExchangeCodes() : 100);
        merchant.setMaxOrdersPerMonth(request.getMaxOrdersPerMonth() != null ? request.getMaxOrdersPerMonth() : 100);
        
        MerchantDto merchantDto = merchantService.createMerchant(merchant);
        
        // Return success response with user and merchant info
        RegistrationSuccessResponse response = new RegistrationSuccessResponse();
        response.setMessage("Merchant registered successfully");
        response.setUser(userDto);
        response.setMerchant(merchantDto);
        
        return ResponseEntity.ok(response);
    }
    
    // Admin endpoint to onboard merchants with premium plans
    @PostMapping("/admin/merchant")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> onboardMerchant(@RequestBody AdminOnboardRequest request) {
        // Check if username or email already exists
        if (userService.existsByUsername(request.getUsername())) {
            return ResponseEntity.badRequest().body(new ErrorResponse("Username is already taken"));
        }
        
        if (userService.existsByEmail(request.getEmail())) {
            return ResponseEntity.badRequest().body(new ErrorResponse("Email is already in use"));
        }
        
        // Create user account
        User user = new User();
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setPassword(request.getPassword());
        user.setPhone(request.getPhone());
        user.setUserType(User.UserType.MERCHANT);
        
        UserDto userDto = userService.createUser(user);
        
        // Create merchant profile with admin-specified settings
        Merchant merchant = new Merchant();
        merchant.setUserId(userDto.getId());
        merchant.setBusinessName(request.getBusinessName());
        merchant.setBusinessLicense(request.getBusinessLicense());
        merchant.setContactPerson(request.getContactPerson());
        merchant.setAddress(request.getAddress());
        merchant.setSubscriptionType(request.getSubscriptionType() != null ? request.getSubscriptionType() : Merchant.SubscriptionType.FREE);
        merchant.setSubscriptionStartDate(request.getSubscriptionStartDate() != null ? request.getSubscriptionStartDate() : LocalDate.now());
        merchant.setSubscriptionEndDate(request.getSubscriptionEndDate());
        merchant.setMaxProducts(request.getMaxProducts() != null ? request.getMaxProducts() : 10);
        merchant.setMaxExchangeCodes(request.getMaxExchangeCodes() != null ? request.getMaxExchangeCodes() : 100);
        merchant.setMaxOrdersPerMonth(request.getMaxOrdersPerMonth() != null ? request.getMaxOrdersPerMonth() : 100);
        
        MerchantDto merchantDto = merchantService.createMerchant(merchant);
        
        // Return success response with user and merchant info
        RegistrationSuccessResponse response = new RegistrationSuccessResponse();
        response.setMessage("Merchant onboarded successfully");
        response.setUser(userDto);
        response.setMerchant(merchantDto);
        
        return ResponseEntity.ok(response);
    }
    
    // Request classes
    public static class MerchantRegistrationRequest {
        private String username;
        private String email;
        private String password;
        private String phone;
        private String businessName;
        private String businessLicense;
        private String contactPerson;
        private String address;
        private Integer maxProducts;
        private Integer maxExchangeCodes;
        private Integer maxOrdersPerMonth;
        
        // Getters and setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        
        public String getBusinessName() { return businessName; }
        public void setBusinessName(String businessName) { this.businessName = businessName; }
        
        public String getBusinessLicense() { return businessLicense; }
        public void setBusinessLicense(String businessLicense) { this.businessLicense = businessLicense; }
        
        public String getContactPerson() { return contactPerson; }
        public void setContactPerson(String contactPerson) { this.contactPerson = contactPerson; }
        
        public String getAddress() { return address; }
        public void setAddress(String address) { this.address = address; }
        
        public Integer getMaxProducts() { return maxProducts; }
        public void setMaxProducts(Integer maxProducts) { this.maxProducts = maxProducts; }
        
        public Integer getMaxExchangeCodes() { return maxExchangeCodes; }
        public void setMaxExchangeCodes(Integer maxExchangeCodes) { this.maxExchangeCodes = maxExchangeCodes; }
        
        public Integer getMaxOrdersPerMonth() { return maxOrdersPerMonth; }
        public void setMaxOrdersPerMonth(Integer maxOrdersPerMonth) { this.maxOrdersPerMonth = maxOrdersPerMonth; }
    }
    
    public static class AdminOnboardRequest {
        private String username;
        private String email;
        private String password;
        private String phone;
        private String businessName;
        private String businessLicense;
        private String contactPerson;
        private String address;
        private Merchant.SubscriptionType subscriptionType;
        private java.time.LocalDate subscriptionStartDate;
        private java.time.LocalDate subscriptionEndDate;
        private Integer maxProducts;
        private Integer maxExchangeCodes;
        private Integer maxOrdersPerMonth;
        
        // Getters and setters
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        
        public String getBusinessName() { return businessName; }
        public void setBusinessName(String businessName) { this.businessName = businessName; }
        
        public String getBusinessLicense() { return businessLicense; }
        public void setBusinessLicense(String businessLicense) { this.businessLicense = businessLicense; }
        
        public String getContactPerson() { return contactPerson; }
        public void setContactPerson(String contactPerson) { this.contactPerson = contactPerson; }
        
        public String getAddress() { return address; }
        public void setAddress(String address) { this.address = address; }
        
        public Merchant.SubscriptionType getSubscriptionType() { return subscriptionType; }
        public void setSubscriptionType(Merchant.SubscriptionType subscriptionType) { this.subscriptionType = subscriptionType; }
        
        public java.time.LocalDate getSubscriptionStartDate() { return subscriptionStartDate; }
        public void setSubscriptionStartDate(java.time.LocalDate subscriptionStartDate) { this.subscriptionStartDate = subscriptionStartDate; }
        
        public java.time.LocalDate getSubscriptionEndDate() { return subscriptionEndDate; }
        public void setSubscriptionEndDate(java.time.LocalDate subscriptionEndDate) { this.subscriptionEndDate = subscriptionEndDate; }
        
        public Integer getMaxProducts() { return maxProducts; }
        public void setMaxProducts(Integer maxProducts) { this.maxProducts = maxProducts; }
        
        public Integer getMaxExchangeCodes() { return maxExchangeCodes; }
        public void setMaxExchangeCodes(Integer maxExchangeCodes) { this.maxExchangeCodes = maxExchangeCodes; }
        
        public Integer getMaxOrdersPerMonth() { return maxOrdersPerMonth; }
        public void setMaxOrdersPerMonth(Integer maxOrdersPerMonth) { this.maxOrdersPerMonth = maxOrdersPerMonth; }
    }
    
    public static class ErrorResponse {
        private String message;
        
        public ErrorResponse(String message) {
            this.message = message;
        }
        
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }
    
    public static class RegistrationSuccessResponse {
        private String message;
        private UserDto user;
        private MerchantDto merchant;
        
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        
        public UserDto getUser() { return user; }
        public void setUser(UserDto user) { this.user = user; }
        
        public MerchantDto getMerchant() { return merchant; }
        public void setMerchant(MerchantDto merchant) { this.merchant = merchant; }
    }
}